<!DOCTYPE html>


<html lang="en">


<head>
  <meta charset="utf-8" />
    
  <meta name="description" content="小人物,码农" />
  
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
  <title>
    第五章 控制流 |  歆雨小屋
  </title>
  <meta name="generator" content="hexo-theme-ayer">
  
  <link rel="shortcut icon" href="/favicon.ico" />
  
  
<link rel="stylesheet" href="/dist/main.css">

  
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/Shen-Yu/cdn/css/remixicon.min.css">

  
<link rel="stylesheet" href="/css/custom.css">

  
  
<script src="https://cdn.jsdelivr.net/npm/pace-js@1.0.2/pace.min.js"></script>

  
  

  

<link rel="alternate" href="/atom.xml" title="歆雨小屋" type="application/atom+xml">
</head>

</html>

<body>
  <div id="app">
    
      
    <main class="content on">
      <section class="outer">
  <article
  id="post-第五章 控制流"
  class="article article-type-post"
  itemscope
  itemprop="blogPost"
  data-scroll-reveal
>
  <div class="article-inner">
    
    <header class="article-header">
       
<h1 class="article-title sea-center" style="border-left:0" itemprop="name">
  第五章 控制流
</h1>
 

    </header>
     
    <div class="article-meta">
      <a href="/2020/07/26/%E7%AC%AC%E4%BA%94%E7%AB%A0%20%E6%8E%A7%E5%88%B6%E6%B5%81/" class="article-date">
  <time datetime="2020-07-26T14:26:31.000Z" itemprop="datePublished">2020-07-26</time>
</a> 
  <div class="article-category">
    <a class="article-category-link" href="/categories/Java%E7%BC%96%E7%A8%8B%E6%80%9D%E6%83%B3/">Java编程思想</a>
  </div>
  
<div class="word_count">
    <span class="post-time">
        <span class="post-meta-item-icon">
            <i class="ri-quill-pen-line"></i>
            <span class="post-meta-item-text"> Word count:</span>
            <span class="post-count">7.1k</span>
        </span>
    </span>

    <span class="post-time">
        &nbsp; | &nbsp;
        <span class="post-meta-item-icon">
            <i class="ri-book-open-line"></i>
            <span class="post-meta-item-text"> Reading time≈</span>
            <span class="post-count">29 min</span>
        </span>
    </span>
</div>
 
    </div>
      
    <div class="tocbot"></div>




  
    <div class="article-entry" itemprop="articleBody">
       
  <blockquote>
<p>程序必须在执行过程中控制它的世界并做出选择。 在 Java 中，你需要执行控制语句来做出选择。</p>
</blockquote>
<p>Java 使用了 C 的所有执行控制语句，因此对于熟悉 C/C++ 编程的人来说，这部分内容轻车熟路。大多数面向过程编程语言都有共通的某种控制语句。在 Java 中，涉及的关键字包括 <strong>if-else，while，do-while，for，return，break</strong> 和选择语句 <strong>switch</strong>。 Java 并不支持备受诟病的 <strong>goto</strong>（尽管它在某些特殊场景中依然是最行之有效的方法）。 尽管如此，在 Java 中我们仍旧可以进行类似的逻辑跳转，但较之典型的 <strong>goto</strong> 用法限制更多。</p>
<a id="more"></a>
<h2 id="true和false"><a href="#true和false" class="headerlink" title="true和false"></a>true和false</h2><p>所有的条件语句都利用条件表达式的“真”或“假”来决定执行路径。举例：<br><code>a == b</code>。它利用了条件表达式 <code>==</code> 来比较 <code>a</code> 与 <code>b</code> 的值是否相等。 该表达式返回 <code>true</code> 或 <code>false</code>。代码示例：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// control/TrueFalse.java</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">TrueFalse</span> </span>&#123;</span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">		System.out.println(<span class="number">1</span> == <span class="number">1</span>);</span><br><span class="line">		System.out.println(<span class="number">1</span> == <span class="number">2</span>);</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>输出结果：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">true false</span><br></pre></td></tr></table></figure>

<p>通过上一章的学习，我们知道任何关系运算符都可以产生条件语句。 <strong>注意</strong>：在 Java 中使用数值作为布尔值是非法的，即便这种操作在 C/C++ 中是被允许的（在这些语言中，“真”为非零，而“假”是零）。如果想在布尔测试中使用一个非布尔值，那么首先需要使用条件表达式来产生 <strong>boolean</strong> 类型的结果，例如 <code>if(a != 0)</code>。</p>
<h2 id="if-else"><a href="#if-else" class="headerlink" title="if-else"></a>if-else</h2><p><strong>if-else</strong> 语句是控制程序执行流程最基本的形式。 其中 <code>else</code> 是可选的，因此可以有两种形式的 <code>if</code>。代码示例：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span>(Boolean-expression) </span><br><span class="line">	“statement”</span><br></pre></td></tr></table></figure>

<p>或</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span>(Boolean-expression) </span><br><span class="line">	“statement”</span><br><span class="line"><span class="keyword">else</span></span><br><span class="line">  “statement”</span><br></pre></td></tr></table></figure>

<p>布尔表达式（Boolean-expression）必须生成 <strong>boolean</strong> 类型的结果，执行语句 <code>statement</code> 既可以是以分号 <code>;</code> 结尾的一条简单语句，也可以是包含在大括号 <code>{}</code> 内的的复合语句 —— 封闭在大括号内的一组简单语句。 凡本书中提及“statement”一词，皆表示类似的执行语句。</p>
<p>下面是一个有关 <strong>if-else</strong> 语句的例子。<code>test()</code> 方法可以告知你两个数值之间的大小关系。代码示例：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// control/IfElse.java</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">IfElse</span> </span>&#123;</span><br><span class="line">  <span class="keyword">static</span> <span class="keyword">int</span> result = <span class="number">0</span>;</span><br><span class="line">  <span class="function"><span class="keyword">static</span> <span class="keyword">void</span> <span class="title">test</span><span class="params">(<span class="keyword">int</span> testval, <span class="keyword">int</span> target)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(testval &gt; target)</span><br><span class="line">      result = +<span class="number">1</span>;</span><br><span class="line">    <span class="keyword">else</span> <span class="keyword">if</span>(testval &lt; target) <span class="comment">// [1]</span></span><br><span class="line">      result = -<span class="number">1</span>;</span><br><span class="line">    <span class="keyword">else</span></span><br><span class="line">      result = <span class="number">0</span>; <span class="comment">// Match</span></span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">    test(<span class="number">10</span>, <span class="number">5</span>);</span><br><span class="line">    System.out.println(result);</span><br><span class="line">    test(<span class="number">5</span>, <span class="number">10</span>);</span><br><span class="line">    System.out.println(result);</span><br><span class="line">    test(<span class="number">5</span>, <span class="number">5</span>);</span><br><span class="line">    System.out.println(result);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>输出结果：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">1</span><br><span class="line">-1</span><br><span class="line">0</span><br></pre></td></tr></table></figure>

<p><sub><strong>注解</strong>：<code>else if</code> 并非新关键字，它仅是 <code>else</code> 后紧跟的一条新 <code>if</code> 语句。</sub></p>
<p>Java 和 C/C++ 同属“自由格式”的编程语言，但通常我们会在 Java 控制流程语句中采用首部缩进的规范，以便代码更具可读性。</p>
<!--Iteration Statements-->
<h2 id="迭代语句"><a href="#迭代语句" class="headerlink" title="迭代语句"></a>迭代语句</h2><p><strong>while</strong>，<strong>do-while</strong> 和 <strong>for</strong> 用来控制循环语句（有时也称迭代语句）。只有控制循环的布尔表达式计算结果为 <code>false</code>，循环语句才会停止。 </p>
<h3 id="while"><a href="#while" class="headerlink" title="while"></a>while</h3><p><strong>while</strong> 循环的形式是：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">while</span>(Boolean-expression) </span><br><span class="line">  statement</span><br></pre></td></tr></table></figure>

<p>执行语句会在每一次循环前，判断布尔表达式返回值是否为 <code>true</code>。下例可产生随机数，直到满足特定条件。代码示例：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// control/WhileTest.java</span></span><br><span class="line"><span class="comment">// 演示 while 循环</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">WhileTest</span> </span>&#123;</span><br><span class="line">  <span class="function"><span class="keyword">static</span> <span class="keyword">boolean</span> <span class="title">condition</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    <span class="keyword">boolean</span> result = Math.random() &lt; <span class="number">0.99</span>;</span><br><span class="line">    System.out.print(result + <span class="string">", "</span>);</span><br><span class="line">    <span class="keyword">return</span> result;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">while</span>(condition())</span><br><span class="line">      System.out.println(<span class="string">"Inside 'while'"</span>);</span><br><span class="line">    System.out.println(<span class="string">"Exited 'while'"</span>);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>输出结果：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">true, Inside &#39;while&#39;</span><br><span class="line">true, Inside &#39;while&#39;</span><br><span class="line">true, Inside &#39;while&#39;</span><br><span class="line">true, Inside &#39;while&#39;</span><br><span class="line">true, Inside &#39;while&#39;</span><br><span class="line">...________...________...________...________...</span><br><span class="line">true, Inside &#39;while&#39;</span><br><span class="line">true, Inside &#39;while&#39;</span><br><span class="line">true, Inside &#39;while&#39;</span><br><span class="line">true, Inside &#39;while&#39;</span><br><span class="line">false, Exited &#39;while&#39;</span><br></pre></td></tr></table></figure>

<p><code>condition()</code> 方法使用到了 <strong>Math</strong> 库的<strong>静态</strong>方法 <code>random()</code>。该方法的作用是产生 0 和 1 之间 (包括 0，但不包括 1) 的一个 <strong>double</strong> 值。</p>
<p><strong>result</strong> 的值是通过比较运算符 <code>&lt;</code> 产生的 <strong>boolean</strong> 类型的结果。当控制台输出 <strong>boolean</strong> 型值时，会自动将其转换为对应的文字形式 <code>true</code> 或 <code>false</code>。此处 <code>while</code> 条件表达式代表：“仅在 <code>condition()</code> 返回 <code>false</code> 时停止循环”。</p>
<h3 id="do-while"><a href="#do-while" class="headerlink" title="do-while"></a>do-while</h3><p><strong>do-while</strong> 的格式如下：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">do</span> </span><br><span class="line">	statement</span><br><span class="line"><span class="keyword">while</span>(Boolean-expression);</span><br></pre></td></tr></table></figure>

<p><strong>while</strong> 和 <strong>do-while</strong> 之间的唯一区别是：即使条件表达式返回结果为 <code>false</code>， <strong>do-while</strong> 语句也至少会执行一次。 在 <strong>while</strong> 循环体中，如布尔表达式首次返回的结果就为 <code>false</code>，那么循环体内的语句不会被执行。实际应用中，<strong>while</strong> 形式比 <strong>do-while</strong> 更为常用。</p>
<h3 id="for"><a href="#for" class="headerlink" title="for"></a>for</h3><p><strong>for</strong> 循环可能是最常用的迭代形式。 该循环在第一次迭代之前执行初始化。随后，它会执行布尔表达式，并在每次迭代结束时，进行某种形式的步进。<strong>for</strong> 循环的形式是：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">for</span>(initialization; Boolean-expression; step)</span><br><span class="line">  statement</span><br></pre></td></tr></table></figure>

<p>初始化 (initialization) 表达式、布尔表达式 (Boolean-expression) ，或者步进 (step) 运算，都可以为空。每次迭代之前都会判断布尔表达式的结果是否成立。一旦计算结果为 <code>false</code>，则跳出 <strong>for</strong> 循环体并继续执行后面代码。 每次循环结束时，都会执行一次步进。</p>
<p><strong>for</strong> 循环通常用于“计数”任务。代码示例：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// control/ListCharacters.java</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ListCharacters</span> </span>&#123;</span><br><span class="line">  <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">char</span> c = <span class="number">0</span>; c &lt; <span class="number">128</span>; c++)</span><br><span class="line">      <span class="keyword">if</span>(Character.isLowerCase(c))</span><br><span class="line">        System.out.println(<span class="string">"value: "</span> + (<span class="keyword">int</span>)c +</span><br><span class="line">          <span class="string">" character: "</span> + c);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>输出结果（前 10 行）：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">value: 97 character: a</span><br><span class="line">value: 98 character: b</span><br><span class="line">value: 99 character: c</span><br><span class="line">value: 100 character: d</span><br><span class="line">value: 101 character: e</span><br><span class="line">value: 102 character: f</span><br><span class="line">value: 103 character: g</span><br><span class="line">value: 104 character: h</span><br><span class="line">value: 105 character: i</span><br><span class="line">value: 106 character: j</span><br><span class="line">  ...</span><br></pre></td></tr></table></figure>


<p><strong>注意</strong>：变量 <strong>c</strong> 是在 <strong>for</strong> 循环执行时才被定义的，并不是在主方法的开头。<strong>c</strong> 的作用域范围仅在 <strong>for</strong> 循环体内。</p>
<p>传统的面向过程语言如 C 需要先在代码块（block）前定义好所有变量才能够使用。这样编译器才能在创建块时，为这些变量分配内存空间。在 Java 和 C++ 中，我们可以在整个块使用变量声明，并且可以在需要时才定义变量。 这种自然的编码风格使我们的代码更容易被人理解 [^1]。</p>
<p>上例使用了 <strong>java.lang.Character</strong> 包装类，该类不仅包含了基本类型 <code>char</code> 的值，还封装了一些有用的方法。例如这里就用到了静态方法 <code>isLowerCase()</code> 来判断字符是否为小写。</p>
<!--The Comma Operator-->

<h4 id="逗号操作符"><a href="#逗号操作符" class="headerlink" title="逗号操作符"></a>逗号操作符</h4><p>在 Java 中逗号运算符（这里并非指我们平常用于分隔定义和方法参数的逗号分隔符）仅有一种用法：在 <strong>for</strong> 循环的初始化和步进控制中定义多个变量。我们可以使用逗号分隔多个语句，并按顺序计算这些语句。<strong>注意</strong>：要求定义的变量类型相同。代码示例：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// control/CommaOperator.java</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">CommaOperator</span> </span>&#123;</span><br><span class="line">  <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">1</span>, j = i + <span class="number">10</span>; i &lt; <span class="number">5</span>; i++, j = i * <span class="number">2</span>) &#123;</span><br><span class="line">      System.out.println(<span class="string">"i = "</span> + i + <span class="string">" j = "</span> + j);</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>输出结果：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">i &#x3D; 1 j &#x3D; 11</span><br><span class="line">i &#x3D; 2 j &#x3D; 4</span><br><span class="line">i &#x3D; 3 j &#x3D; 6</span><br><span class="line">i &#x3D; 4 j &#x3D; 8</span><br></pre></td></tr></table></figure>


<p>上例中 <strong>int</strong> 类型声明包含了 <code>i</code> 和 <code>j</code>。实际上，在初始化部分我们可以定义任意数量的同类型变量。<strong>注意</strong>：在 Java 中，仅允许 <strong>for</strong> 循环在控制表达式中定义变量。 我们不能将此方法与其他的循环语句和选择语句中一起使用。同时，我们可以看到：无论在初始化还是在步进部分，语句都是顺序执行的。</p>
<h2 id="for-in-语法"><a href="#for-in-语法" class="headerlink" title="for-in 语法"></a>for-in 语法</h2><p>Java 5 引入了更为简洁的“增强版 <strong>for</strong> 循环”语法来操纵数组和集合。（更多细节，可参考 <a href="./21-Arrays.md">数组</a> 和 <a href="./12-Collections.md">集合</a> 章节内容）。大部分文档也称其为 <strong>for-each</strong> 语法，但因为了不与 Java 8 新添的 <code>forEach()</code> 产生混淆，因此我称之为 <strong>for-in</strong> 循环。 （Python 已有类似的先例，如：<strong>for x in sequence</strong>）。<strong>注意</strong>：你可能会在其他地方看到不同叫法。</p>
<p><strong>for-in</strong> 无需你去创建 <strong>int</strong> 变量和步进来控制循环计数。 下面我们来遍历获取 <strong>float</strong> 数组中的元素。代码示例：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// control/ForInFloat.java</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.util.*;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ForInFloat</span> </span>&#123;</span><br><span class="line">  <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">    Random rand = <span class="keyword">new</span> Random(<span class="number">47</span>);</span><br><span class="line">    <span class="keyword">float</span>[] f = <span class="keyword">new</span> <span class="keyword">float</span>[<span class="number">10</span>];</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; <span class="number">10</span>; i++)</span><br><span class="line">      f[i] = rand.nextFloat();</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">float</span> x : f)</span><br><span class="line">      System.out.println(x);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>输出结果：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">0.72711575</span><br><span class="line">0.39982635</span><br><span class="line">0.5309454</span><br><span class="line">0.0534122</span><br><span class="line">0.16020656</span><br><span class="line">0.57799757</span><br><span class="line">0.18847865</span><br><span class="line">0.4170137</span><br><span class="line">0.51660204</span><br><span class="line">0.73734957</span><br></pre></td></tr></table></figure>

<p>上例中我们展示了传统 <strong>for</strong> 循环的用法。接下来再来看下 <strong>for-in</strong> 的用法。代码示例：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">for</span>(<span class="keyword">float</span> x : f) &#123;</span><br></pre></td></tr></table></figure>

<p>这条语句定义了一个 <strong>float</strong> 类型的变量 <code>x</code>，继而将每一个 <code>f</code> 的元素赋值给它。</p>
<p>任何一个返回数组的方法都可以使用 <strong>for-in</strong> 循环语法来遍历元素。例如 <strong>String</strong> 类有一个方法 <code>toCharArray()</code>，返回值类型为 <strong>char</strong> 数组，我们可以很容易地在 <strong>for-in</strong> 循环中遍历它。代码示例：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// control/ForInString.java</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ForInString</span> </span>&#123;</span><br><span class="line">  <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">char</span> c: <span class="string">"An African Swallow"</span>.toCharArray())</span><br><span class="line">      System.out.print(c + <span class="string">" "</span>);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>输出结果：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">A n   A f r i c a n   S w a l l o w</span><br></pre></td></tr></table></figure>

<p>很快我们能在 <a href="./12-Collections.md">集合</a> 章节里学习到，<strong>for-in</strong> 循环适用于任何可迭代（<em>iterable</em>）的 对象。</p>
<p>通常，<strong>for</strong> 循环语句都会在一个整型数值序列中步进。代码示例：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; <span class="number">100</span>; i++)</span><br></pre></td></tr></table></figure>

<p>正因如此，除非先创建一个 <strong>int</strong> 数组，否则我们无法使用 <strong>for-in</strong> 循环来操作。为简化测试过程，我已在 <code>onjava</code> 包中封装了 <strong>Range</strong> 类，利用其 <code>range()</code> 方法可自动生成恰当的数组。</p>
<p>在 <a href="./07-Implementation-Hiding.md">封装</a>（Implementation Hiding）这一章里我们介绍了静态导入（static import），无需了解细节就可以直接使用。 有关静态导入的语法，可以在 <strong>import</strong> 语句中看到：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// control/ForInInt.java</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> <span class="keyword">static</span> onjava.Range.*;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ForInInt</span> </span>&#123;</span><br><span class="line">  <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">int</span> i : range(<span class="number">10</span>)) <span class="comment">// 0..9</span></span><br><span class="line">      System.out.print(i + <span class="string">" "</span>);</span><br><span class="line">    System.out.println();</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">int</span> i : range(<span class="number">5</span>, <span class="number">10</span>)) <span class="comment">// 5..9</span></span><br><span class="line">      System.out.print(i + <span class="string">" "</span>);</span><br><span class="line">    System.out.println();</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">int</span> i : range(<span class="number">5</span>, <span class="number">20</span>, <span class="number">3</span>)) <span class="comment">// 5..20 step 3</span></span><br><span class="line">      System.out.print(i + <span class="string">" "</span>);</span><br><span class="line">    System.out.println();</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">int</span> i : range(<span class="number">20</span>, <span class="number">5</span>, -<span class="number">3</span>)) <span class="comment">// Count down</span></span><br><span class="line">      System.out.print(i + <span class="string">" "</span>);</span><br><span class="line">    System.out.println();</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>输出结果：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">0 1 2 3 4 5 6 7 8 9</span><br><span class="line">5 6 7 8 9</span><br><span class="line">5 8 11 14 17</span><br><span class="line">20 17 14 11 8</span><br></pre></td></tr></table></figure>

<p><code>range()</code> 方法已被 <a href="./06-Housekeeping.md#方法重载">重载</a>（重载：同名方法，参数列表或类型不同）。上例中 <code>range()</code> 方法有多种重载形式：第一种产生从 0 至范围上限（不包含）的值；第二种产生参数一至参数二（不包含）范围内的整数值；第三种形式有一个步进值，因此它每次的增量为该值；第四种 <code>range()</code> 表明还可以递减。<code>range()</code> 无参方法是该生成器最简单的版本。有关内容会在本书稍后介绍。</p>
<p><code>range()</code> 的使用提高了代码可读性，让 <strong>for-in</strong> 循环在本书中适应更多的代码示例场景。</p>
<p>请注意，<code>System.out.print()</code> 不会输出换行符，所以我们可以分段输出同一行。</p>
<p><em>for-in</em> 语法可以节省我们编写代码的时间。 更重要的是，它提高了代码可读性以及更好地描述代码意图（获取数组的每个元素）而不是详细说明这操作细节（创建索引，并用它来选择数组元素） 本书推荐使用 <em>for-in</em> 语法。</p>
<h2 id="return"><a href="#return" class="headerlink" title="return"></a>return</h2><p>在 Java 中有几个关键字代表无条件分支，这意味无需任何测试即可发生。这些关键字包括 <strong>return</strong>，<strong>break</strong>，<strong>continue</strong> 和跳转到带标签语句的方法，类似于其他语言中的 <strong>goto</strong>。</p>
<p><strong>return</strong> 关键字有两方面的作用：1.指定一个方法返回值 (在方法返回类型非 <strong>void</strong> 的情况下)；2.退出当前方法，并返回作用 1 中值。我们可以利用 <code>return</code> 的这些特点来改写上例 <code>IfElse.java</code> 文件中的 <code>test()</code> 方法。代码示例：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// control/TestWithReturn.java</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">TestWithReturn</span> </span>&#123;</span><br><span class="line">  <span class="function"><span class="keyword">static</span> <span class="keyword">int</span> <span class="title">test</span><span class="params">(<span class="keyword">int</span> testval, <span class="keyword">int</span> target)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(testval &gt; target)</span><br><span class="line">      <span class="keyword">return</span> +<span class="number">1</span>;</span><br><span class="line">    <span class="keyword">if</span>(testval &lt; target)</span><br><span class="line">      <span class="keyword">return</span> -<span class="number">1</span>;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>; <span class="comment">// Match</span></span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">    System.out.println(test(<span class="number">10</span>, <span class="number">5</span>));</span><br><span class="line">    System.out.println(test(<span class="number">5</span>, <span class="number">10</span>));</span><br><span class="line">    System.out.println(test(<span class="number">5</span>, <span class="number">5</span>));</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>输出结果：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">1</span><br><span class="line">-1</span><br><span class="line">0</span><br></pre></td></tr></table></figure>

<p>这里不需要 <code>else</code>，因为该方法执行到 <code>return</code> 就结束了。</p>
<p>如果在方法签名中定义了返回值类型为 <strong>void</strong>，那么在代码执行结束时会有一个隐式的 <strong>return</strong>。 也就是说我们不用在总是在方法中显式地包含 <strong>return</strong> 语句。 <strong>注意</strong>：如果你的方法声明的返回值类型为非 <strong>void</strong> 类型，那么则必须确保每个代码路径都返回一个值。</p>
<h2 id="break-和-continue"><a href="#break-和-continue" class="headerlink" title="break 和 continue"></a>break 和 continue</h2><p>在任何迭代语句的主体内，都可以使用 <strong>break</strong> 和 <strong>continue</strong> 来控制循环的流程。 其中，<strong>break</strong> 表示跳出当前循环体。而 <strong>continue</strong> 表示停止本次循环，开始下一次循环。</p>
<p>下例向大家展示 <strong>break</strong> 和 <strong>continue</strong> 在 <strong>for</strong>、<strong>while</strong> 循环中的使用。代码示例：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// control/BreakAndContinue.java</span></span><br><span class="line"><span class="comment">// Break 和 continue 关键字</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> <span class="keyword">static</span> onjava.Range.*;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">BreakAndContinue</span> </span>&#123;</span><br><span class="line">  <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; <span class="number">100</span>; i++) &#123; <span class="comment">// [1]</span></span><br><span class="line">      <span class="keyword">if</span>(i == <span class="number">74</span>) <span class="keyword">break</span>; <span class="comment">// 跳出循环</span></span><br><span class="line">      <span class="keyword">if</span>(i % <span class="number">9</span> != <span class="number">0</span>) <span class="keyword">continue</span>; <span class="comment">// 下一次循环</span></span><br><span class="line">      System.out.print(i + <span class="string">" "</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    System.out.println();</span><br><span class="line">    <span class="comment">// 使用 for-in 循环:</span></span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">int</span> i : range(<span class="number">100</span>)) &#123; <span class="comment">// [2]</span></span><br><span class="line">      <span class="keyword">if</span>(i == <span class="number">74</span>) <span class="keyword">break</span>; <span class="comment">// 跳出循环</span></span><br><span class="line">      <span class="keyword">if</span>(i % <span class="number">9</span> != <span class="number">0</span>) <span class="keyword">continue</span>; <span class="comment">// 下一次循环</span></span><br><span class="line">      System.out.print(i + <span class="string">" "</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    System.out.println();</span><br><span class="line">    <span class="keyword">int</span> i = <span class="number">0</span>;</span><br><span class="line">    <span class="comment">//  "无限循环":</span></span><br><span class="line">    <span class="keyword">while</span>(<span class="keyword">true</span>) &#123; <span class="comment">// [3]</span></span><br><span class="line">      i++;</span><br><span class="line">      <span class="keyword">int</span> j = i * <span class="number">27</span>;</span><br><span class="line">      <span class="keyword">if</span>(j == <span class="number">1269</span>) <span class="keyword">break</span>; <span class="comment">// 跳出循环</span></span><br><span class="line">      <span class="keyword">if</span>(i % <span class="number">10</span> != <span class="number">0</span>) <span class="keyword">continue</span>; <span class="comment">// 循环顶部</span></span><br><span class="line">      System.out.print(i + <span class="string">" "</span>);</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>输出结果:</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">0 9 18 27 36 45 54 63 72</span><br><span class="line">0 9 18 27 36 45 54 63 72</span><br><span class="line">10 20 30 40</span><br></pre></td></tr></table></figure>

<p>  <sub><strong>[1]</strong> 在这个 <strong>for</strong> 循环中，<code>i</code> 的值永远不会达到 100，因为一旦 <code>i</code> 等于 74，<strong>break</strong> 语句就会中断循环。通常，只有在不知道中断条件何时满足时，才需要 <strong>break</strong>。因为 <code>i</code> 不能被 9 整除，<strong>continue</strong> 语句就会使循环从头开始。这使 <strong>i</strong> 递增)。如果能够整除，则将值显示出来。</sub><br>  <sub><strong>[2]</strong> 使用 <strong>for-in</strong> 语法，结果相同。</sub><br>  <sub><strong>[3]</strong> 无限 <strong>while</strong> 循环。循环内的 <strong>break</strong> 语句可中止循环。<strong>注意</strong>，<strong>continue</strong> 语句可将控制权移回循环的顶部，而不会执行 <strong>continue</strong> 之后的任何操作。 因此，只有当 <code>i</code> 的值可被 10 整除时才会输出。在输出中，显示值 0，因为 <code>0％9</code> 产生 0。还有一种无限循环的形式： <code>for(;;)</code>。 在编译器看来，它与 <code>while(true)</code> 无异，使用哪种完全取决于你的编程品味。</sub></p>
<!--The Infamous “Goto”-->
<h2 id="臭名昭著的-goto"><a href="#臭名昭著的-goto" class="headerlink" title="臭名昭著的 goto"></a>臭名昭著的 goto</h2><p><a href="https://en.wikipedia.org/wiki/Goto" target="_blank" rel="noopener"><strong>goto</strong> 关键字</a> 很早就在程序设计语言中出现。事实上，<strong>goto</strong> 起源于<a href="https://en.wikipedia.org/wiki/Assembly_language" target="_blank" rel="noopener">汇编</a>（assembly language）语言中的程序控制：“若条件 A 成立，则跳到这里；否则跳到那里”。如果你读过由编译器编译后的代码，你会发现在其程序控制中充斥了大量的跳转。较之汇编产生的代码直接运行在硬件 CPU 中，Java 也会产生自己的“汇编代码”（字节码），只不过它是运行在 Java 虚拟机里的（Java Virtual Machine）。</p>
<p>一个源码级别跳转的 <strong>goto</strong>，为何招致名誉扫地呢？若程序总是从一处跳转到另一处，还有什么办法能识别代码的控制流程呢？随着 <em>Edsger Dijkstra</em>发表著名的 “Goto 有害” 论（<em>Goto considered harmful</em>）以后，<strong>goto</strong> 便从此失宠。甚至有人建议将它从关键字中剔除。</p>
<p>正如上述提及的经典情况，我们不应走向两个极端。问题不在 <strong>goto</strong>，而在于过度使用 <strong>goto</strong>。在极少数情况下，<strong>goto</strong> 实际上是控制流程的最佳方式。</p>
<p>尽管 <strong>goto</strong> 仍是 Java 的一个保留字，但其并未被正式启用。可以说， Java 中并不支持 <strong>goto</strong>。然而，在 <strong>break</strong> 和 <strong>continue</strong> 这两个关键字的身上，我们仍能看出一些 <strong>goto</strong> 的影子。它们并不属于一次跳转，而是中断循环语句的一种方法。之所以把它们纳入 <strong>goto</strong> 问题中一起讨论，是由于它们使用了相同的机制：标签。</p>
<p>“标签”是后面跟一个冒号的标识符。代码示例：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">label1:</span><br></pre></td></tr></table></figure>

<p>对 Java 来说，唯一用到标签的地方是在循环语句之前。进一步说，它实际需要紧靠在循环语句的前方 —— 在标签和循环之间置入任何语句都是不明智的。而在循环之前设置标签的唯一理由是：我们希望在其中嵌套另一个循环或者一个开关。这是由于 <strong>break</strong> 和 <strong>continue</strong> 关键字通常只中断当前循环，但若搭配标签一起使用，它们就会中断并跳转到标签所在的地方开始执行。代码示例：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">label1:</span><br><span class="line">outer-iteration &#123; </span><br><span class="line">  inner-iteration &#123;</span><br><span class="line">  <span class="comment">// ...</span></span><br><span class="line">  <span class="keyword">break</span>; <span class="comment">// [1] </span></span><br><span class="line">  <span class="comment">// ...</span></span><br><span class="line">  <span class="keyword">continue</span>; <span class="comment">// [2] </span></span><br><span class="line">  <span class="comment">// ...</span></span><br><span class="line">  <span class="keyword">continue</span> label1; <span class="comment">// [3] </span></span><br><span class="line">  <span class="comment">// ...</span></span><br><span class="line">  <span class="keyword">break</span> label1; <span class="comment">// [4] </span></span><br><span class="line">  &#125; </span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><sub><strong>[1]</strong> <strong>break</strong> 中断内部循环，并在外部循环结束。</sub><br><sub><strong>[2]</strong> <strong>continue</strong> 移回内部循环的起始处。但在条件 3 中，<strong>continue label1</strong> 却同时中断内部循环以及外部循环，并移至 <strong>label1</strong> 处。</sub><br><sub><strong>[3]</strong> 随后，它实际是继续循环，但却从外部循环开始。</sub><br><sub><strong>[4]</strong> <strong>break label1</strong> 也会中断所有循环，并回到 <strong>label1</strong> 处，但并不重新进入循环。也就是说，它实际是完全中止了两个循环。</sub></p>
<p>下面是 <strong>for</strong> 循环的一个例子：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// control/LabeledFor.java</span></span><br><span class="line"><span class="comment">// 搭配“标签 break”的 for 循环中使用 break 和 continue</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">LabeledFor</span> </span>&#123;</span><br><span class="line">  <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span> i = <span class="number">0</span>;</span><br><span class="line">    outer: <span class="comment">// 此处不允许存在执行语句</span></span><br><span class="line">    <span class="keyword">for</span>(; <span class="keyword">true</span> ;) &#123; <span class="comment">// 无限循环</span></span><br><span class="line">      inner: <span class="comment">// 此处不允许存在执行语句</span></span><br><span class="line">      <span class="keyword">for</span>(; i &lt; <span class="number">10</span>; i++) &#123;</span><br><span class="line">        System.out.println(<span class="string">"i = "</span> + i);</span><br><span class="line">        <span class="keyword">if</span>(i == <span class="number">2</span>) &#123;</span><br><span class="line">          System.out.println(<span class="string">"continue"</span>);</span><br><span class="line">          <span class="keyword">continue</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span>(i == <span class="number">3</span>) &#123;</span><br><span class="line">          System.out.println(<span class="string">"break"</span>);</span><br><span class="line">          i++; <span class="comment">// 否则 i 永远无法获得自增 </span></span><br><span class="line">               <span class="comment">// 获得自增 </span></span><br><span class="line">          <span class="keyword">break</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span>(i == <span class="number">7</span>) &#123;</span><br><span class="line">          System.out.println(<span class="string">"continue outer"</span>);</span><br><span class="line">          i++;  <span class="comment">// 否则 i 永远无法获得自增 </span></span><br><span class="line">                <span class="comment">// 获得自增 </span></span><br><span class="line">          <span class="keyword">continue</span> outer;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span>(i == <span class="number">8</span>) &#123;</span><br><span class="line">          System.out.println(<span class="string">"break outer"</span>);</span><br><span class="line">          <span class="keyword">break</span> outer;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> k = <span class="number">0</span>; k &lt; <span class="number">5</span>; k++) &#123;</span><br><span class="line">          <span class="keyword">if</span>(k == <span class="number">3</span>) &#123;</span><br><span class="line">            System.out.println(<span class="string">"continue inner"</span>);</span><br><span class="line">            <span class="keyword">continue</span> inner;</span><br><span class="line">          &#125;</span><br><span class="line">        &#125;</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">// 在此处无法 break 或 continue 标签</span></span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>输出结果：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">i &#x3D; 0</span><br><span class="line">continue inner</span><br><span class="line">i &#x3D; 1</span><br><span class="line">continue inner</span><br><span class="line">i &#x3D; 2</span><br><span class="line">continue</span><br><span class="line">i &#x3D; 3</span><br><span class="line">break</span><br><span class="line">i &#x3D; 4</span><br><span class="line">continue inner</span><br><span class="line">i &#x3D; 5</span><br><span class="line">continue inner</span><br><span class="line">i &#x3D; 6</span><br><span class="line">continue inner</span><br><span class="line">i &#x3D; 7</span><br><span class="line">continue outer</span><br><span class="line">i &#x3D; 8</span><br><span class="line">break outer</span><br></pre></td></tr></table></figure>


<p>注意 <strong>break</strong> 会中断 <strong>for</strong> 循环，而且在抵达 <strong>for</strong> 循环的末尾之前，递增表达式不会执行。由于 <strong>break</strong> 跳过了递增表达式，所以递增会在 <code>i==3</code> 的情况下直接执行。在 <code>i==7</code> 的情况下，<code>continue outer</code> 语句也会到达循环顶部，而且也会跳过递增，所以它也是直接递增的。</p>
<p>如果没有 <strong>break outer</strong> 语句，就没有办法在一个内部循环里找到出外部循环的路径。这是由于 <strong>break</strong> 本身只能中断最内层的循环（对于 <strong>continue</strong> 同样如此）。 当然，若想在中断循环的同时退出方法，简单地用一个 <strong>return</strong> 即可。</p>
<p>下面这个例子向大家展示了带标签的 <strong>break</strong> 以及 <strong>continue</strong> 语句在 <strong>while</strong> 循环中的用法：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// control/LabeledWhile.java</span></span><br><span class="line"><span class="comment">// 带标签的 break 和 conitue 在 while 循环中的使用</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">LabeledWhile</span> </span>&#123;</span><br><span class="line">  <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span> i = <span class="number">0</span>;</span><br><span class="line">    outer:</span><br><span class="line">    <span class="keyword">while</span>(<span class="keyword">true</span>) &#123;</span><br><span class="line">      System.out.println(<span class="string">"Outer while loop"</span>);</span><br><span class="line">      <span class="keyword">while</span>(<span class="keyword">true</span>) &#123;</span><br><span class="line">        i++;</span><br><span class="line">        System.out.println(<span class="string">"i = "</span> + i);</span><br><span class="line">        <span class="keyword">if</span>(i == <span class="number">1</span>) &#123;</span><br><span class="line">          System.out.println(<span class="string">"continue"</span>);</span><br><span class="line">          <span class="keyword">continue</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span>(i == <span class="number">3</span>) &#123;</span><br><span class="line">          System.out.println(<span class="string">"continue outer"</span>);</span><br><span class="line">          <span class="keyword">continue</span> outer;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span>(i == <span class="number">5</span>) &#123;</span><br><span class="line">          System.out.println(<span class="string">"break"</span>);</span><br><span class="line">          <span class="keyword">break</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span>(i == <span class="number">7</span>) &#123;</span><br><span class="line">          System.out.println(<span class="string">"break outer"</span>);</span><br><span class="line">          <span class="keyword">break</span> outer;</span><br><span class="line">        &#125;</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>输出结果：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">Outer while loop</span><br><span class="line">i &#x3D; 1</span><br><span class="line">continue</span><br><span class="line">i &#x3D; 2</span><br><span class="line">i &#x3D; 3</span><br><span class="line">continue outer</span><br><span class="line">Outer while loop</span><br><span class="line">i &#x3D; 4</span><br><span class="line">i &#x3D; 5</span><br><span class="line">break</span><br><span class="line">Outer while loop</span><br><span class="line">i &#x3D; 6</span><br><span class="line">i &#x3D; 7</span><br><span class="line">break outer</span><br></pre></td></tr></table></figure>

<p>同样的规则亦适用于 <strong>while</strong>：</p>
<ol>
<li><p>简单的一个 <strong>continue</strong> 会退回最内层循环的开头（顶部），并继续执行。</p>
</li>
<li><p>带有标签的 <strong>continue</strong> 会到达标签的位置，并重新进入紧接在那个标签后面的循环。</p>
</li>
<li><p><strong>break</strong> 会中断当前循环，并移离当前标签的末尾。</p>
</li>
<li><p>带标签的 <strong>break</strong> 会中断当前循环，并移离由那个标签指示的循环的末尾。</p>
</li>
</ol>
<p>大家要记住的重点是：在 Java 里需要使用标签的唯一理由就是因为有循环嵌套存在，而且想从多层嵌套中 <strong>break</strong> 或 <strong>continue</strong>。</p>
<p><strong>break</strong> 和 <strong>continue</strong> 标签在编码中的使用频率相对较低 (此前的语言中很少使用或没有先例)，所以我们很少在代码里看到它们。</p>
<p>在 <em>Dijkstra</em> 的 <strong>“Goto 有害”</strong> 论文中，他最反对的就是标签，而非 <strong>goto</strong>。他观察到 BUG 的数量似乎随着程序中标签的数量而增加[^2]。标签和 <strong>goto</strong> 使得程序难以分析。但是，Java 标签不会造成这方面的问题，因为它们的应用场景受到限制，无法用于以临时方式传输控制。由此也引出了一个有趣的情形：对语言能力的限制，反而使它这项特性更加有价值。</p>
<h2 id="switch"><a href="#switch" class="headerlink" title="switch"></a>switch</h2><p><strong>switch</strong> 有时也被划归为一种选择语句。根据整数表达式的值，<strong>switch</strong> 语句可以从一系列代码中选出一段去执行。它的格式如下：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">switch</span>(integral-selector) &#123;</span><br><span class="line">	<span class="keyword">case</span> integral-value1 : statement; <span class="keyword">break</span>;</span><br><span class="line">	<span class="keyword">case</span> integral-value2 : statement;	<span class="keyword">break</span>;</span><br><span class="line">	<span class="keyword">case</span> integral-value3 : statement;	<span class="keyword">break</span>;</span><br><span class="line">	<span class="keyword">case</span> integral-value4 : statement;	<span class="keyword">break</span>;</span><br><span class="line">	<span class="keyword">case</span> integral-value5 : statement;	<span class="keyword">break</span>;</span><br><span class="line">	<span class="comment">// ...</span></span><br><span class="line">	<span class="keyword">default</span>: statement;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>其中，<strong>integral-selector</strong> （整数选择因子）是一个能够产生整数值的表达式，<strong>switch</strong> 能够将这个表达式的结果与每个 <strong>integral-value</strong> （整数值）相比较。若发现相符的，就执行对应的语句（简单或复合语句，其中并不需要括号）。若没有发现相符的，就执行  <strong>default</strong> 语句。</p>
<p>在上面的定义中，大家会注意到每个 <strong>case</strong> 均以一个 <strong>break</strong> 结尾。这样可使执行流程跳转至 <strong>switch</strong> 主体的末尾。这是构建 <strong>switch</strong> 语句的一种传统方式，但 <strong>break</strong> 是可选的。若省略 <strong>break，</strong> 会继续执行后面的 <strong>case</strong> 语句的代码，直到遇到一个 <strong>break</strong> 为止。通常我们不想出现这种情况，但对有经验的程序员来说，也许能够善加利用。注意最后的 <strong>default</strong> 语句没有 <strong>break</strong>，因为执行流程已到了 <strong>break</strong> 的跳转目的地。当然，如果考虑到编程风格方面的原因，完全可以在 <strong>default</strong> 语句的末尾放置一个 <strong>break</strong>，尽管它并没有任何实际的作用。</p>
<p><strong>switch</strong> 语句是一种实现多路选择的干净利落的一种方式（比如从一系列执行路径中挑选一个）。但它要求使用一个选择因子，并且必须是 <strong>int</strong> 或 <strong>char</strong> 那样的整数值。例如，假若将一个字串或者浮点数作为选择因子使用，那么它们在 switch 语句里是不会工作的。对于非整数类型（Java 7 以上版本中的 String 型除外），则必须使用一系列 <strong>if</strong> 语句。 在<a href="./06-Housekeeping.md#枚举类型">下一章的结尾</a> 中，我们将会了解到<strong>枚举类型</strong>被用来搭配 <strong>switch</strong> 工作，并优雅地解决了这种限制。</p>
<p>下面这个例子可随机生成字母，并判断它们是元音还是辅音字母：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// control/VowelsAndConsonants.java</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// switch 执行语句的演示</span></span><br><span class="line"><span class="keyword">import</span> java.util.*;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">VowelsAndConsonants</span> </span>&#123;</span><br><span class="line">  <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">    Random rand = <span class="keyword">new</span> Random(<span class="number">47</span>);</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; <span class="number">100</span>; i++) &#123;</span><br><span class="line">      <span class="keyword">int</span> c = rand.nextInt(<span class="number">26</span>) + <span class="string">'a'</span>;</span><br><span class="line">      System.out.print((<span class="keyword">char</span>)c + <span class="string">", "</span> + c + <span class="string">": "</span>);</span><br><span class="line">      <span class="keyword">switch</span>(c) &#123;</span><br><span class="line">        <span class="keyword">case</span> <span class="string">'a'</span>:</span><br><span class="line">        <span class="keyword">case</span> <span class="string">'e'</span>:</span><br><span class="line">        <span class="keyword">case</span> <span class="string">'i'</span>:</span><br><span class="line">        <span class="keyword">case</span> <span class="string">'o'</span>:</span><br><span class="line">        <span class="keyword">case</span> <span class="string">'u'</span>: System.out.println(<span class="string">"vowel"</span>);</span><br><span class="line">                  <span class="keyword">break</span>;</span><br><span class="line">        <span class="keyword">case</span> <span class="string">'y'</span>:</span><br><span class="line">        <span class="keyword">case</span> <span class="string">'w'</span>: System.out.println(<span class="string">"Sometimes vowel"</span>);</span><br><span class="line">                  <span class="keyword">break</span>;</span><br><span class="line">        <span class="keyword">default</span>:  System.out.println(<span class="string">"consonant"</span>);</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>输出结果：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">y, 121: Sometimes vowel</span><br><span class="line">n, 110: consonant</span><br><span class="line">z, 122: consonant</span><br><span class="line">b, 98: consonant</span><br><span class="line">r, 114: consonant</span><br><span class="line">n, 110: consonant</span><br><span class="line">y, 121: Sometimes vowel</span><br><span class="line">g, 103: consonant</span><br><span class="line">c, 99: consonant</span><br><span class="line">f, 102: consonant</span><br><span class="line">o, 111: vowel</span><br><span class="line">w, 119: Sometimes vowel</span><br><span class="line">z, 122: consonant</span><br><span class="line">  ...</span><br></pre></td></tr></table></figure>

<p>由于 <code>Random.nextInt(26)</code> 会产生 0 到 25 之间的一个值，所以在其上加上一个偏移量 <code>a</code>，即可产生小写字母。在 <strong>case</strong> 语句中，使用单引号引起的字符也会产生用于比较的整数值。</p>
<p>请注意 <strong>case</strong> 语句能够堆叠在一起，为一段代码形成多重匹配，即只要符合多种条件中的一种，就执行那段特别的代码。这时也应该注意将 <strong>break</strong> 语句置于特定 <strong>case</strong> 的末尾，否则控制流程会继续往下执行，处理后面的 <strong>case</strong>。在下面的语句中：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">int</span> c = rand.nextInt(<span class="number">26</span>) + <span class="string">'a'</span>;</span><br></pre></td></tr></table></figure>

<p>此处 <code>Random.nextInt()</code> 将产生 0~25 之间的一个随机 <strong>int</strong> 值，它将被加到 <code>a</code> 上。这表示 <code>a</code> 将自动被转换为 <strong>int</strong> 以执行加法。为了把 <code>c</code> 当作字符打印，必须将其转型为 <strong>char</strong>；否则，将会输出整数。</p>
<!-- Switching on Strings -->

<h2 id="switch-字符串"><a href="#switch-字符串" class="headerlink" title="switch 字符串"></a>switch 字符串</h2><p>Java 7 增加了在字符串上 <strong>switch</strong> 的用法。 下例展示了从一组 <strong>String</strong> 中选择可能值的传统方法，以及新式方法：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// control/StringSwitch.java</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">StringSwitch</span> </span>&#123;</span><br><span class="line">  <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">    String color = <span class="string">"red"</span>;</span><br><span class="line">    <span class="comment">// 老的方式: 使用 if-then 判断</span></span><br><span class="line">    <span class="keyword">if</span>(<span class="string">"red"</span>.equals(color)) &#123;</span><br><span class="line">      System.out.println(<span class="string">"RED"</span>);</span><br><span class="line">    &#125; <span class="keyword">else</span> <span class="keyword">if</span>(<span class="string">"green"</span>.equals(color)) &#123;</span><br><span class="line">      System.out.println(<span class="string">"GREEN"</span>);</span><br><span class="line">    &#125; <span class="keyword">else</span> <span class="keyword">if</span>(<span class="string">"blue"</span>.equals(color)) &#123;</span><br><span class="line">      System.out.println(<span class="string">"BLUE"</span>);</span><br><span class="line">    &#125; <span class="keyword">else</span> <span class="keyword">if</span>(<span class="string">"yellow"</span>.equals(color)) &#123;</span><br><span class="line">      System.out.println(<span class="string">"YELLOW"</span>);</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">      System.out.println(<span class="string">"Unknown"</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">// 新的方法: 字符串搭配 switch</span></span><br><span class="line">    <span class="keyword">switch</span>(color) &#123;</span><br><span class="line">      <span class="keyword">case</span> <span class="string">"red"</span>:</span><br><span class="line">        System.out.println(<span class="string">"RED"</span>);</span><br><span class="line">        <span class="keyword">break</span>;</span><br><span class="line">      <span class="keyword">case</span> <span class="string">"green"</span>:</span><br><span class="line">        System.out.println(<span class="string">"GREEN"</span>);</span><br><span class="line">        <span class="keyword">break</span>;</span><br><span class="line">      <span class="keyword">case</span> <span class="string">"blue"</span>:</span><br><span class="line">        System.out.println(<span class="string">"BLUE"</span>);</span><br><span class="line">        <span class="keyword">break</span>;</span><br><span class="line">      <span class="keyword">case</span> <span class="string">"yellow"</span>:</span><br><span class="line">        System.out.println(<span class="string">"YELLOW"</span>);</span><br><span class="line">        <span class="keyword">break</span>;</span><br><span class="line">      <span class="keyword">default</span>:</span><br><span class="line">        System.out.println(<span class="string">"Unknown"</span>);</span><br><span class="line">        <span class="keyword">break</span>;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>输出结果：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">RED</span><br><span class="line">RED</span><br></pre></td></tr></table></figure>


<p>一旦理解了 <strong>switch</strong>，你会明白这其实就是一个逻辑扩展的语法糖。新的编码方式能使得结果更清晰，更易于理解和维护。</p>
<p>作为 <strong>switch</strong> 字符串的第二个例子，我们重新访问 <code>Math.random()</code>。 它是否产生从 0 到 1 的值，包括还是不包括值 1 呢？在数学术语中，它属于 (0,1)、[0,1)、(0,1]、[0,1] 中的哪种呢？（方括号表示“包括”，而括号表示“不包括”）</p>
<p>下面是一个可能提供答案的测试程序。 所有命令行参数都作为 <strong>String</strong> 对象传递，因此我们可以 <strong>switch</strong> 参数来决定要做什么。 那么问题来了：如果用户不提供参数 ，索引到 <code>args</code> 的数组就会导致程序失败。 解决这个问题，我们需要预先检查数组的长度，若长度为 0，则使用<strong>空字符串</strong> <code>&quot;&quot;</code> 替代；否则，选择 <code>args</code> 数组中的第一个元素：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// control/RandomBounds.java</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// Math.random() 会产生 0.0 和 1.0 吗？</span></span><br><span class="line"><span class="comment">// &#123;java RandomBounds lower&#125;</span></span><br><span class="line"><span class="keyword">import</span> onjava.*;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">RandomBounds</span> </span>&#123;</span><br><span class="line">  <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">new</span> TimedAbort(<span class="number">3</span>);</span><br><span class="line">    <span class="keyword">switch</span>(args.length == <span class="number">0</span> ? <span class="string">""</span> : args[<span class="number">0</span>]) &#123;</span><br><span class="line">      <span class="keyword">case</span> <span class="string">"lower"</span>:</span><br><span class="line">        <span class="keyword">while</span>(Math.random() != <span class="number">0.0</span>)</span><br><span class="line">          ; <span class="comment">// 保持重试</span></span><br><span class="line">        System.out.println(<span class="string">"Produced 0.0!"</span>);</span><br><span class="line">        <span class="keyword">break</span>;</span><br><span class="line">      <span class="keyword">case</span> <span class="string">"upper"</span>:</span><br><span class="line">        <span class="keyword">while</span>(Math.random() != <span class="number">1.0</span>)</span><br><span class="line">          ; <span class="comment">// 保持重试</span></span><br><span class="line">        System.out.println(<span class="string">"Produced 1.0!"</span>);</span><br><span class="line">        <span class="keyword">break</span>;</span><br><span class="line">      <span class="keyword">default</span>:</span><br><span class="line">        System.out.println(<span class="string">"Usage:"</span>);</span><br><span class="line">        System.out.println(<span class="string">"\tRandomBounds lower"</span>);</span><br><span class="line">        System.out.println(<span class="string">"\tRandomBounds upper"</span>);</span><br><span class="line">        System.exit(<span class="number">1</span>);</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>要运行该程序，请键入以下任一命令：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">java RandomBounds lower </span><br><span class="line"><span class="comment">// 或者</span></span><br><span class="line">java RandomBounds upper</span><br></pre></td></tr></table></figure>

<p>使用 <code>onjava</code> 包中的 <strong>TimedAbort</strong> 类可使程序在三秒后中止。从结果来看，似乎 <code>Math.random()</code> 产生的随机值里不包含 0.0 或 1.0。 这就是该测试容易混淆的地方：若要考虑 0 至 1 之间所有不同 <strong>double</strong> 数值的可能性，那么这个测试的耗费的时间可能超出一个人的寿命了。 这里我们直接给出正确的结果：<code>Math.random()</code> 的结果集范围包含 0.0 ，不包含 1.0。 在数学术语中，可用 [0,1) 来表示。由此可知，我们必须小心分析实验并了解它们的局限性。</p>
<h2 id="本章小结"><a href="#本章小结" class="headerlink" title="本章小结"></a>本章小结</h2><p>本章总结了我们对大多数编程语言中出现的基本特性的探索：计算，运算符优先级，类型转换，选择和迭代。 现在让我们准备好，开始步入面向对象和函数式编程的世界吧。 下一章的内容涵盖了 Java 编程中的重要问题：对象的<a href="./06-Housekeeping.md">初始化和清理</a>。紧接着，还会介绍<a href="./07-Implementation-Hiding.md">封装</a>（implementation hiding）的核心概念。</p>
<!--下面是脚注-->
<p>[^1]: 在早期的语言中，许多决策都是基于让编译器设计者的体验更好。 但在现代语言设计中，许多决策都是为了提高语言使用者的体验，尽管有时会有妥协 —— 这通常会让语言设计者后悔。</p>
<p>[^2]: <strong>注意</strong>，此处观点似乎难以让人信服，很可能只是一个因认知偏差而造成的<a href="https://en.wikipedia.org/wiki/Correlation_does_not_imply_causation" target="_blank" rel="noopener">因果关系谬误</a> 的例子。</p>
<!-- 分页 -->

<div style="page-break-after: always;"></div>
 
      <!-- reward -->
      
    </div>
    

    <!-- copyright -->
    
    <footer class="article-footer">
       
<div class="share-btn">
      <span class="share-sns share-outer">
        <i class="ri-share-forward-line"></i>
        分享
      </span>
      <div class="share-wrap">
        <i class="arrow"></i>
        <div class="share-icons">
          
          <a class="weibo share-sns" href="javascript:;" data-type="weibo">
            <i class="ri-weibo-fill"></i>
          </a>
          <a class="weixin share-sns wxFab" href="javascript:;" data-type="weixin">
            <i class="ri-wechat-fill"></i>
          </a>
          <a class="qq share-sns" href="javascript:;" data-type="qq">
            <i class="ri-qq-fill"></i>
          </a>
          <a class="douban share-sns" href="javascript:;" data-type="douban">
            <i class="ri-douban-line"></i>
          </a>
          <!-- <a class="qzone share-sns" href="javascript:;" data-type="qzone">
            <i class="icon icon-qzone"></i>
          </a> -->
          
          <a class="facebook share-sns" href="javascript:;" data-type="facebook">
            <i class="ri-facebook-circle-fill"></i>
          </a>
          <a class="twitter share-sns" href="javascript:;" data-type="twitter">
            <i class="ri-twitter-fill"></i>
          </a>
          <a class="google share-sns" href="javascript:;" data-type="google">
            <i class="ri-google-fill"></i>
          </a>
        </div>
      </div>
</div>

<div class="wx-share-modal">
    <a class="modal-close" href="javascript:;"><i class="ri-close-circle-line"></i></a>
    <p>扫一扫，分享到微信</p>
    <div class="wx-qrcode">
      <img src="//api.qrserver.com/v1/create-qr-code/?size=150x150&data=http://yoursite.com/2020/07/26/%E7%AC%AC%E4%BA%94%E7%AB%A0%20%E6%8E%A7%E5%88%B6%E6%B5%81/" alt="微信分享二维码">
    </div>
</div>

<div id="share-mask"></div>  
  <ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/Java%E7%BC%96%E7%A8%8B%E6%80%9D%E6%83%B3/" rel="tag">Java编程思想</a></li><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/OnJava8/" rel="tag">OnJava8</a></li></ul>

    </footer>
  </div>

   
  <nav class="article-nav">
    
      <a href="/2020/07/27/%E7%AC%AC%E5%85%AD%E7%AB%A0%20%E5%88%9D%E5%A7%8B%E5%8C%96%E5%92%8C%E6%B8%85%E7%90%86/" class="article-nav-link">
        <strong class="article-nav-caption">上一篇</strong>
        <div class="article-nav-title">
          
            第六章 初始化和清理
          
        </div>
      </a>
    
    
      <a href="/2020/07/25/%E7%AC%AC%E5%9B%9B%E7%AB%A0%20%E8%BF%90%E7%AE%97%E7%AC%A6/" class="article-nav-link">
        <strong class="article-nav-caption">下一篇</strong>
        <div class="article-nav-title">第四章 运算符</div>
      </a>
    
  </nav>

   
<!-- valine评论 -->
<div id="vcomments-box">
  <div id="vcomments"></div>
</div>
<script src="//cdn1.lncld.net/static/js/3.0.4/av-min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/valine@1.4.14/dist/Valine.min.js"></script>
<script>
  new Valine({
    el: "#vcomments",
    app_id: "",
    app_key: "",
    path: window.location.pathname,
    avatar: "monsterid",
    placeholder: "给我的文章加点评论吧~",
    recordIP: true,
  });
  const infoEle = document.querySelector("#vcomments .info");
  if (infoEle && infoEle.childNodes && infoEle.childNodes.length > 0) {
    infoEle.childNodes.forEach(function (item) {
      item.parentNode.removeChild(item);
    });
  }
</script>
<style>
  #vcomments-box {
    padding: 5px 30px;
  }

  @media screen and (max-width: 800px) {
    #vcomments-box {
      padding: 5px 0px;
    }
  }

  #vcomments-box #vcomments {
    background-color: #fff;
  }

  .v .vlist .vcard .vh {
    padding-right: 20px;
  }

  .v .vlist .vcard {
    padding-left: 10px;
  }
</style>

 
     
</article>

</section>
      <footer class="footer">
  <div class="outer">
    <ul>
      <li>
        Copyrights &copy;
        2015-2020
        <i class="ri-heart-fill heart_icon"></i> Gghui
      </li>
    </ul>
  </div>
</footer>
      <div class="float_btns">
        <div class="totop" id="totop">
  <i class="ri-arrow-up-line"></i>
</div>

<div class="todark" id="todark">
  <i class="ri-moon-line"></i>
</div>

      </div>
    </main>
    <aside class="sidebar on">
      <button class="navbar-toggle"></button>
<nav class="navbar">
  
  <div class="logo">
    <a href="/"><img src="/images/ayer-side.svg" alt="歆雨小屋"></a>
  </div>
  
  <ul class="nav nav-main">
    
    <li class="nav-item">
      <a class="nav-item-link" href="/">主页</a>
    </li>
    
    <li class="nav-item">
      <a class="nav-item-link" href="/archives">归档</a>
    </li>
    
    <li class="nav-item">
      <a class="nav-item-link" href="/categories">分类</a>
    </li>
    
    <li class="nav-item">
      <a class="nav-item-link" href="/tags">标签</a>
    </li>
    
  </ul>
</nav>
<nav class="navbar navbar-bottom">
  <ul class="nav">
    <li class="nav-item">
      
      <a class="nav-item-link nav-item-search"  title="Search">
        <i class="ri-search-line"></i>
      </a>
      
      
      <a class="nav-item-link" target="_blank" href="/atom.xml" title="RSS Feed">
        <i class="ri-rss-line"></i>
      </a>
      
    </li>
  </ul>
</nav>
<div class="search-form-wrap">
  <div class="local-search local-search-plugin">
  <input type="search" id="local-search-input" class="local-search-input" placeholder="Search...">
  <div id="local-search-result" class="local-search-result"></div>
</div>
</div>
    </aside>
    <script>
      if (window.matchMedia("(max-width: 768px)").matches) {
        document.querySelector('.content').classList.remove('on');
        document.querySelector('.sidebar').classList.remove('on');
      }
    </script>
    <div id="mask"></div>

<!-- #reward -->
<div id="reward">
  <span class="close"><i class="ri-close-line"></i></span>
  <p class="reward-p"><i class="ri-cup-line"></i>请我喝杯咖啡吧~</p>
  <div class="reward-box">
    
    <div class="reward-item">
      <img class="reward-img" src="https://cdn.jsdelivr.net/gh/Shen-Yu/cdn/img/alipay.jpg">
      <span class="reward-type">支付宝</span>
    </div>
    
    
    <div class="reward-item">
      <img class="reward-img" src="https://cdn.jsdelivr.net/gh/Shen-Yu/cdn/img/wechat.jpg">
      <span class="reward-type">微信</span>
    </div>
    
  </div>
</div>
    
<script src="/js/jquery-2.0.3.min.js"></script>


<script src="/js/lazyload.min.js"></script>

<!-- Tocbot -->


<script src="/js/tocbot.min.js"></script>

<script>
  tocbot.init({
    tocSelector: '.tocbot',
    contentSelector: '.article-entry',
    headingSelector: 'h1, h2, h3, h4, h5, h6',
    hasInnerContainers: true,
    scrollSmooth: true,
    scrollContainer: 'main',
    positionFixedSelector: '.tocbot',
    positionFixedClass: 'is-position-fixed',
    fixedSidebarOffset: 'auto'
  });
</script>

<script src="https://cdn.jsdelivr.net/npm/jquery-modal@0.9.2/jquery.modal.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/jquery-modal@0.9.2/jquery.modal.min.css">
<script src="https://cdn.jsdelivr.net/npm/justifiedGallery@3.7.0/dist/js/jquery.justifiedGallery.min.js"></script>

<script src="/dist/main.js"></script>

<!-- ImageViewer -->

<!-- Root element of PhotoSwipe. Must have class pswp. -->
<div class="pswp" tabindex="-1" role="dialog" aria-hidden="true">

    <!-- Background of PhotoSwipe. 
         It's a separate element as animating opacity is faster than rgba(). -->
    <div class="pswp__bg"></div>

    <!-- Slides wrapper with overflow:hidden. -->
    <div class="pswp__scroll-wrap">

        <!-- Container that holds slides. 
            PhotoSwipe keeps only 3 of them in the DOM to save memory.
            Don't modify these 3 pswp__item elements, data is added later on. -->
        <div class="pswp__container">
            <div class="pswp__item"></div>
            <div class="pswp__item"></div>
            <div class="pswp__item"></div>
        </div>

        <!-- Default (PhotoSwipeUI_Default) interface on top of sliding area. Can be changed. -->
        <div class="pswp__ui pswp__ui--hidden">

            <div class="pswp__top-bar">

                <!--  Controls are self-explanatory. Order can be changed. -->

                <div class="pswp__counter"></div>

                <button class="pswp__button pswp__button--close" title="Close (Esc)"></button>

                <button class="pswp__button pswp__button--share" style="display:none" title="Share"></button>

                <button class="pswp__button pswp__button--fs" title="Toggle fullscreen"></button>

                <button class="pswp__button pswp__button--zoom" title="Zoom in/out"></button>

                <!-- Preloader demo http://codepen.io/dimsemenov/pen/yyBWoR -->
                <!-- element will get class pswp__preloader--active when preloader is running -->
                <div class="pswp__preloader">
                    <div class="pswp__preloader__icn">
                        <div class="pswp__preloader__cut">
                            <div class="pswp__preloader__donut"></div>
                        </div>
                    </div>
                </div>
            </div>

            <div class="pswp__share-modal pswp__share-modal--hidden pswp__single-tap">
                <div class="pswp__share-tooltip"></div>
            </div>

            <button class="pswp__button pswp__button--arrow--left" title="Previous (arrow left)">
            </button>

            <button class="pswp__button pswp__button--arrow--right" title="Next (arrow right)">
            </button>

            <div class="pswp__caption">
                <div class="pswp__caption__center"></div>
            </div>

        </div>

    </div>

</div>

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/photoswipe.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/default-skin/default-skin.min.css">
<script src="https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/photoswipe.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/photoswipe-ui-default.min.js"></script>

<script>
    function viewer_init() {
        let pswpElement = document.querySelectorAll('.pswp')[0];
        let $imgArr = document.querySelectorAll(('.article-entry img:not(.reward-img)'))

        $imgArr.forEach(($em, i) => {
            $em.onclick = () => {
                // slider展开状态
                // todo: 这样不好，后面改成状态
                if (document.querySelector('.left-col.show')) return
                let items = []
                $imgArr.forEach(($em2, i2) => {
                    let img = $em2.getAttribute('data-idx', i2)
                    let src = $em2.getAttribute('data-target') || $em2.getAttribute('src')
                    let title = $em2.getAttribute('alt')
                    // 获得原图尺寸
                    const image = new Image()
                    image.src = src
                    items.push({
                        src: src,
                        w: image.width || $em2.width,
                        h: image.height || $em2.height,
                        title: title
                    })
                })
                var gallery = new PhotoSwipe(pswpElement, PhotoSwipeUI_Default, items, {
                    index: parseInt(i)
                });
                gallery.init()
            }
        })
    }
    viewer_init()
</script>

<!-- MathJax -->

<!-- Katex -->

<!-- busuanzi  -->


<script src="/js/busuanzi-2.3.pure.min.js"></script>


<!-- ClickLove -->

<!-- ClickBoom1 -->

<!-- ClickBoom2 -->

<!-- CodeCopy -->


<link rel="stylesheet" href="/css/clipboard.css">

<script src="https://cdn.jsdelivr.net/npm/clipboard@2/dist/clipboard.min.js"></script>
<script>
  function wait(callback, seconds) {
    var timelag = null;
    timelag = window.setTimeout(callback, seconds);
  }
  !function (e, t, a) {
    var initCopyCode = function(){
      var copyHtml = '';
      copyHtml += '<button class="btn-copy" data-clipboard-snippet="">';
      copyHtml += '<i class="ri-file-copy-2-line"></i><span>COPY</span>';
      copyHtml += '</button>';
      $(".highlight .code pre").before(copyHtml);
      $(".article pre code").before(copyHtml);
      var clipboard = new ClipboardJS('.btn-copy', {
        target: function(trigger) {
          return trigger.nextElementSibling;
        }
      });
      clipboard.on('success', function(e) {
        let $btn = $(e.trigger);
        $btn.addClass('copied');
        let $icon = $($btn.find('i'));
        $icon.removeClass('ri-file-copy-2-line');
        $icon.addClass('ri-checkbox-circle-line');
        let $span = $($btn.find('span'));
        $span[0].innerText = 'COPIED';
        
        wait(function () { // 等待两秒钟后恢复
          $icon.removeClass('ri-checkbox-circle-line');
          $icon.addClass('ri-file-copy-2-line');
          $span[0].innerText = 'COPY';
        }, 2000);
      });
      clipboard.on('error', function(e) {
        e.clearSelection();
        let $btn = $(e.trigger);
        $btn.addClass('copy-failed');
        let $icon = $($btn.find('i'));
        $icon.removeClass('ri-file-copy-2-line');
        $icon.addClass('ri-time-line');
        let $span = $($btn.find('span'));
        $span[0].innerText = 'COPY FAILED';
        
        wait(function () { // 等待两秒钟后恢复
          $icon.removeClass('ri-time-line');
          $icon.addClass('ri-file-copy-2-line');
          $span[0].innerText = 'COPY';
        }, 2000);
      });
    }
    initCopyCode();
  }(window, document);
</script>


<!-- CanvasBackground -->


    
    <div id="music">
    
    
    
    <iframe frameborder="no" border="1" marginwidth="0" marginheight="0" width="200" height="52"
        src="//music.163.com/outchain/player?type=2&id=371362&auto=1&height=32"></iframe>
</div>

<style>
    #music {
        position: fixed;
        right: 15px;
        bottom: 0;
        z-index: 998;
    }
</style>
    
  </div>
</body>

</html>